package felix.rule.data.msg;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.UUID;

/**
 * @author Felix
 * @date 2020/8/24
 */
@Data
@Slf4j
public final class EngineMsg implements Serializable {

    private final String queueName;
    private final UUID id;
    private final long ts;
    private final String type;
    private final String originator;
    private final EngineMsgMetaData metaData;
    private final EngineMsgDataType dataType;
    private final String data;
    private final String ruleChainId;
    private final String ruleNodeId;
    /**
     * 取消回调函数的json序列化
     */
    @JsonIgnore
    transient private final EngineMsgCallback callback;

    private EngineMsg(String queueName, UUID id, long ts, String type, String originator, EngineMsgMetaData metaData, EngineMsgDataType dataType, String data,
                      String ruleChainId, String ruleNodeId, EngineMsgCallback callback) {
        this.id = id;
        this.queueName = queueName;
        if (ts > 0) {
            this.ts = ts;
        } else {
            this.ts = System.currentTimeMillis();
        }
        this.type = type;
        this.originator = originator;
        this.metaData = metaData;
        this.dataType = dataType;
        this.data = data;
        this.ruleChainId = ruleChainId;
        this.ruleNodeId = ruleNodeId;
        if (callback != null) {
            this.callback = callback;
        } else {
            this.callback = EngineMsgCallback.EMPTY;
        }
    }

    public static EngineMsg newMsg(String type, String originator, EngineMsgMetaData metaData, String data, EngineMsgCallback callback) {
        return new EngineMsg("MAIN", UUID.randomUUID(), System.currentTimeMillis(), type, originator, metaData.copy(), EngineMsgDataType.JSON, data, null, null, callback);
    }

    public static EngineMsg newMsg(String queueName, UUID id, String type, String data) {
        return newMsg(queueName, id, type, new EngineMsgMetaData(), data);
    }

    public static EngineMsg newMsg(String queueName, UUID id, String type, EngineMsgMetaData metaData, String data) {
        return new EngineMsg(queueName, id, System.currentTimeMillis(), type, null, metaData.copy(), EngineMsgDataType.JSON, data, null, null, EngineMsgCallback.EMPTY);
    }

    public static EngineMsg newMsg(String queueName, String type, String originator, EngineMsgMetaData metaData, String data, String ruleChainId, String ruleNodeId) {
        return new EngineMsg(queueName, UUID.randomUUID(), System.currentTimeMillis(), type, originator, metaData.copy(), EngineMsgDataType.JSON, data, ruleChainId, ruleNodeId, EngineMsgCallback.EMPTY);
    }

    public static EngineMsg transformMsg(EngineMsg msg, String ruleChainId, String ruleNodeId) {
        return new EngineMsg(msg.getQueueName(), UUID.randomUUID(), msg.getTs(), msg.getType(), msg.getOriginator(), msg.getMetaData().copy(),
                msg.getDataType(), msg.getData(), ruleChainId, ruleNodeId, EngineMsgCallback.EMPTY);
    }

    public static EngineMsg transformMsg(EngineMsg origMsg, String type, String originator, EngineMsgMetaData metaData, String data) {
        return new EngineMsg(origMsg.getQueueName(), origMsg.getId(), origMsg.getTs(), type, originator, metaData.copy(), origMsg.getDataType(),
                data, origMsg.getRuleChainId(), origMsg.getRuleNodeId(), origMsg.getCallback());
    }

    public EngineMsg copyWithRuleChainId(String ruleChainId) {
        return new EngineMsg(this.queueName, this.id, this.ts, this.type, this.originator, this.metaData, this.dataType, this.data, ruleChainId, null, callback);
    }
}
